import { BaseScraper, type ScrapingResult } from './BaseScraper.js';
import type { DataSourceConfig, ScrapingStrategy } from './types/ScraperConfig.js';
import { ComponentScrapingStrategy } from './strategies/ComponentScrapingStrategy.js';
import { TemplateScrapingStrategy } from './strategies/TemplateScrapingStrategy.js';
import { getEnabledDataSources, getDataSourceConfig } from './config/DataSourceConfigs.js';

/**
 * 通用抓取器
 * 根据配置自动选择合适的抓取策略
 */
export class UniversalScraper extends BaseScraper {
  private strategies: ScrapingStrategy[] = [];

  constructor(private enabledSources?: string[]) {
    super('UniversalScraper', '');
    this.initializeStrategies();
  }

  /**
   * 初始化抓取策略
   */
  private initializeStrategies(): void {
    const dataSources = this.getDataSources();
    
    for (const config of dataSources) {
      const strategy = this.createStrategy(config);
      if (strategy) {
        this.strategies.push(strategy);
      }
    }

    this.log(`📋 初始化了 ${this.strategies.length} 个抓取策略`);
  }

  /**
   * 获取数据源列表
   */
  private getDataSources(): DataSourceConfig[] {
    if (this.enabledSources && this.enabledSources.length > 0) {
      // 使用指定的数据源
      return this.enabledSources
        .map(id => getDataSourceConfig(id))
        .filter((config): config is DataSourceConfig => config !== undefined);
    } else {
      // 使用所有启用的数据源
      return getEnabledDataSources();
    }
  }

  /**
   * 创建抓取策略
   */
  private createStrategy(config: DataSourceConfig): ScrapingStrategy | null {
    try {
      switch (config.type) {
        case 'components':
        case 'charts':
          return new ComponentScrapingStrategy(config);
        case 'templates':
          return new TemplateScrapingStrategy(config);
        default:
          this.warn(`未知的数据源类型: ${config.type}`);
          return null;
      }
    } catch (error) {
      this.error(`创建策略失败 ${config.name}: ${error instanceof Error ? error.message : String(error)}`);
      return null;
    }
  }

  /**
   * 执行抓取
   */
  async scrape(): Promise<ScrapingResult> {
    const startTime = Date.now();
    const result: ScrapingResult = {
      success: false,
      count: 0,
      data: [],
      errors: [],
      timestamp: new Date(),
      duration: 0,
    };

    try {
      this.log('🚀 开始通用数据抓取任务...');
      
      if (this.strategies.length === 0) {
        throw new Error('没有可用的抓取策略');
      }

      this.emitProgress({
        stage: '初始化',
        current: 0,
        total: this.strategies.length,
        message: `准备执行 ${this.strategies.length} 个抓取策略`,
      });

      // 并行执行所有策略
      const results = await Promise.allSettled(
        this.strategies.map(async (strategy, index) => {
          this.emitProgress({
            stage: '执行抓取',
            current: index,
            total: this.strategies.length,
            message: `正在执行 ${strategy.name}...`,
          });

          const strategyResult = await strategy.scrape();
          
          this.emitProgress({
            stage: '执行抓取',
            current: index + 1,
            total: this.strategies.length,
            message: `${strategy.name} 完成，收集 ${strategyResult.count} 项数据`,
          });

          return {
            strategy: strategy.name,
            result: strategyResult
          };
        })
      );

      // 汇总结果
      const allData: any[] = [];
      const allErrors: string[] = [];

      for (const promiseResult of results) {
        if (promiseResult.status === 'fulfilled') {
          const { strategy, result: strategyResult } = promiseResult.value;
          
          if (strategyResult.success) {
            allData.push(...strategyResult.data);
            this.log(`✅ ${strategy} 成功，收集 ${strategyResult.count} 项数据`);
          } else {
            allErrors.push(`${strategy} 失败: ${strategyResult.errors.join(', ')}`);
            this.error(`❌ ${strategy} 失败`);
          }
          
          allErrors.push(...strategyResult.errors);
        } else {
          const errorMsg = `策略执行失败: ${promiseResult.reason}`;
          allErrors.push(errorMsg);
          this.error(errorMsg);
        }
      }

      result.data = allData;
      result.count = allData.length;
      result.errors = allErrors;
      result.success = allData.length > 0;

      this.log(`🎉 通用抓取完成! 总共收集 ${allData.length} 项数据`);

    } catch (error) {
      const errorMsg = `通用抓取失败: ${error instanceof Error ? error.message : String(error)}`;
      result.errors.push(errorMsg);
      this.error(errorMsg);
    }

    result.duration = Date.now() - startTime;
    return result;
  }

  /**
   * 按数据源分别抓取
   */
  async scrapeBySource(): Promise<Record<string, ScrapingResult>> {
    const results: Record<string, ScrapingResult> = {};

    this.log('🚀 开始分源数据抓取任务...');

    for (const strategy of this.strategies) {
      try {
        this.log(`📡 开始抓取: ${strategy.name}`);
        const result = await strategy.scrape();
        results[strategy.name] = result;
        
        if (result.success) {
          this.log(`✅ ${strategy.name} 完成，收集 ${result.count} 项数据`);
        } else {
          this.error(`❌ ${strategy.name} 失败: ${result.errors.join(', ')}`);
        }
      } catch (error) {
        const errorMsg = `${strategy.name} 执行失败: ${error instanceof Error ? error.message : String(error)}`;
        this.error(errorMsg);
        
        results[strategy.name] = {
          success: false,
          count: 0,
          data: [],
          errors: [errorMsg],
          timestamp: new Date(),
          duration: 0,
        };
      }
    }

    return results;
  }

  /**
   * 获取支持的数据源列表
   */
  getSupportedSources(): string[] {
    return this.strategies.map(strategy => strategy.name);
  }

  /**
   * 检查数据源配置
   */
  validateConfigs(): { valid: boolean; errors: string[] } {
    const errors: string[] = [];
    const dataSources = this.getDataSources();

    for (const config of dataSources) {
      // 验证基本配置
      if (!config.id || !config.name || !config.baseUrl) {
        errors.push(`数据源 ${config.id} 缺少必需配置`);
      }

      // 验证抓取配置
      if (!config.scraping.listPage.path || !config.scraping.detailPage.pathPattern) {
        errors.push(`数据源 ${config.id} 抓取配置不完整`);
      }

      // 验证处理配置
      if (!config.processing.imports.defaultPath) {
        errors.push(`数据源 ${config.id} 缺少导入配置`);
      }
    }

    return {
      valid: errors.length === 0,
      errors
    };
  }

  /**
   * 获取配置统计信息
   */
  getConfigStats(): {
    totalSources: number;
    enabledSources: number;
    byType: Record<string, number>;
  } {
    const dataSources = this.getDataSources();
    const byType: Record<string, number> = {};

    for (const config of dataSources) {
      byType[config.type] = (byType[config.type] || 0) + 1;
    }

    return {
      totalSources: dataSources.length,
      enabledSources: dataSources.filter(c => c.enabled).length,
      byType
    };
  }
}